home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
scav31.zip
/
SCAV31.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-10-06
|
13KB
|
541 lines
title scavenge Copyright (c) T. Jennings 1983
;
;****************************************
;* *
;* SCAVENGE *
;* *
;* Mark bad blocks on MSDOS *
;* as allocated in the FAT. *
;* *
;* T. Jennings 5 June 82 *
;* created 15 Sept. 82 *
;* Modified 14 December 1984 *
;* by David Gwillim *
;* *
;* *
;****************************************
;
;See SCAV31.DOC for details on functioning, updates, etc. v3.01
;
;Reads all sectors in logical MSDOS blocks
;and marks the file allocation tables such
;that the blocks are permanently allocated
;where CHKDSK will not deallocate them.
;
;
;This version works on any 2.xx MSDOS or
;PCDOS, on any media type, fixed or removable.
;One (major) limitation: it will not map out
;blocks that are already allocated to a file;
;it will say "block used", but won't tell you
;which file it is in.
;
;If SCAVENGE finds any bad blocks, it will ask
;you whether or not you want the disk updated.
;You can safely run it just to see if the disk
;is OK.
;
;Enter 'Q' at any time to abort the run. v3.01
;MASM, LINK, then EXE2BIN this to make a COM
;file. It will not run as an EXE file. NOTE:
;LINK will give you a 'Warning: no STACK
;segment' error: ignore it.
;
;v3.01
; - Slight tweaking, reformatting.
; - v3.00 forced DS, SS to CS; unnecessary.
; - v3.00 had its own stack; unnecessary.
; - Removed some system functions, placing them inline.
; - Separated extensive documentation into separate file,
; SCAVENGE.DOC.
; - No functional changes.
; David Kirschbaum
; Toad Hall
; kirsch@braggvax.ARPA
CR equ 0dh
LF equ 0ah
PutStr macro ; v3.01
mov ah,9
int 21h
endm
;Beep procedure count values
;---------------------------
;To generate a given freqency note out of the speaker with the Beep procedure
;on the PC using Channel 2 of the 8253 timer, the channel 2 count register
;must be loaded with a value such that the 8253 input clock frequency
;(1.19318 MHz) divided by the count figure equals the audio frequency.
F176HZ equ 6779 ; 176 Hz count value
F352HZ equ 3390 ; 352 Hz count value
F704HZ equ 1695 ; 704 Hz count value
F1408HZ equ 847 ; 1408 Hz count value
page
Cseg segment para public 'code'
assume CS:Cseg, DS:Cseg, ES:Cseg, SS:Cseg
;
;MSDOS PSP stuff.
;
org 5ch
tfcb label byte
org 80h
tbuff label byte
org 100h
Scavenge proc near
jmp Start
;
;Disk parameters:
;
blkcnt dw 0 ;blocks this disk
blksize dw 0 ;sectors per block
secsize dw 0 ;phys. sector size
badcnt dw 0 ;# bad blocks found
newbad dw 0 ;new bad ones
block dw 0 ;current block
sector dw 0 ;sector to read
disk db 0 ;selected disk
curdsk db 0 ;current disk.
fatsec dw 0 ;1st FAT sector,
fatcnt dw 0 ;FAT sec count.
; dw 128 dup 0
;stack dw 0 ;what else
; db 16 dup('STACK ')
;stack equ $
Scavenge endp
page
;
;Say who we are, describe the disk we are
;about to fix, ask to continue or abort.
;
Start proc near
; cli ;Disable interrupts while we move stack
; mov sp,offset stack
; sti ;Re-enable interrupts
mov dx,offset signon
PutStr
mov bx,F176HZ ;Alert user audibly
call Beep
mov bx,F704HZ
call Beep
mov bx,F352HZ
call Beep
mov bx,F1408HZ
call Beep
mov ax,0C08H ;flush, char in with no echo v3.01
int 21h
or al,20h ;Make character lower case
cmp al,'q' ;Quit?
jne St0
mov dx,offset abort
jmp short Msg_Exit ;display, terminate v3.01
St0: call SetUp ;get disk stuff
jnc St1 ;went ok
Msg_Exit: ; v3.01
PutStr
int 20h ;error, terminate.
St1: call ListStat ;describe dsk
;
;Find all the bad blocks, if any, display them,
;ask if we should update the FAT. If so, write
;it out.
;
mov dx,offset crlf ;new line
PutStr
call FindBad ;map bad,
call ListBad ;list them,
cmp newbad,0 ;if new bad
je St2 ;blocks...
mov dx,offset updstr ;ask if we
PutStr ;should update
mov ax,0C08H ;flush, char in with no echo v3.01
int 21h
and al,5fh ;uppercase
mov dx,offset noupdte ;assume no update v3.01
cmp al,'Y'
jne St1B ;nope, no update
mov al,disk ;write out the
mov dx,fatsec ;FAT,
mov cx,fatcnt
mov bx,offset fatbuf
int 26h
pop ax ;pop flags after Int 26H
mov dx,offset update ;fall thru to v3.01
St1B: PutStr ;display msg v3.01
St2:
mov dl,curdsk ;reselect the original disk v3.01
mov ah,0eh ; v3.01
int 21h ; v3.01
int 20h ;terminate
signon db CR,LF,9,'*********************************************'
db CR,LF,9,'* DOS 2.xx Bad Sector Mapper - Version 3.01 *'
db CR,LF,9,'* Updated by David Gwillim 18 December 1984 *'
db CR,LF,9,'* Again by Toad Hall, 6 Oct 88 *'
db CR,LF,9,'* Original program by T. Jennings 5 June 83 *'
db CR,LF,9,'*********************************************'
db CR,LF,LF
db 'Type Q to abort at any time, any other key to continue ...'
db CR,LF,'$'
updstr db CR,LF,LF,'Want the disk updated? [y,n] $'
noupdte db CR,LF,LF,'FAT not updated',CR,LF,'$'
update db CR,LF,LF,'FAT updated'
crlf db CR,LF,'$' ;share this v3.01
Start endp
page
;
;Get the data on the specified disk. Return
;carry if no drive specified. Returns ES:DI
;pointing to the FAT for the selected drive.
;
SetUp proc near
mov ah,0dh ;reset disk system v3.01
int 21h
mov ah,19h ;get current disk v3.01
int 21h
mov curdsk,al ;save it,
mov al,tfcb ;make sure a
cmp al,0 ;new one spec'd
stc ;quit if none,
mov dx,offset strstr ;'Must specify disk drive' msg
jz gd1 ;exit
dec al ;make 0-N,
mov disk,al
mov dl,al ;select disk, v3.01
mov ah,0eh
int 21h
mov di,DS ;save our DS a sec v3.01
mov ah,1bh
int 21h
mov DS,di ;restore DS v3.01
mov blkcnt,dx ;save # blocks,
mov secsize,cx ;sector size,
xor ah,ah ;clear msb v3.01
mov blksize,ax ;secs/block.
mov di,DS ;save DS a sec v3.01
mov dl,disk ;now get the
inc dl ;drive 1=A, b=2
mov ah,32h ;FAT,
int 21h ;get the DPB,
mov cx,[bx+15] ;CX= sec count,
xor ch,ch ;clear msb v3.01
mov dx,[bx+6] ;DX= 1st sec,
mov DS,di ;restore DS v3.01
mov fatcnt,cx ;save both,
mov fatsec,dx
mov al,disk ;AL= drive #,
mov bx,offset fatbuf ;DS:BX= buffer
int 25h ;read the FAT,
pop ax ;pop flags after Int 25H
mov dx,offset bscstr ;return with msg
gd1: ret
strstr db CR,LF,'Must specify a disk drive.$'
bscstr db CR,LF,'Bad FAT sector: disk not useable.$'
SetUp endp
page
;
;Read the entire disk looking for bad blocks.
;When one is found, go mark it as an allocated
;bad block.
;
FindBad proc near
xor ax,ax ;get a handy 0 v3.01
mov block,ax ;1st block,
mov badcnt,ax ;none yet,
BlockLup:
call KbdChk ;QUIT char input from the keyboard?
jnc FB1A ;nope
mov dx,offset abort ;'Aborting program'
PutStr
ret
FB1A: mov dx,offset blkstr ;type 'block '
PutStr
mov bx,block ;block number,
call OutDec
call ReadBlk ;read a block,
jnc Fb3 ;if bad,
inc badcnt ;count it,
mov dx,offset badstr
PutStr ;type 'bad'
call MapOut ;mark bad,
mov dx,offset cntstr ;'Already used'
jc Fb2 ;error if can't
add newbad,cx ;count it,
mov dx,offset alrstr ;'Already marked'
jcxz Fb2 ;error if already marked
mov dx,offset mrkstr ;'mapped out'
mov bx,F704HZ ;Warn user audibly
call Beep
mov bx,F176HZ
call Beep
Fb2: PutStr
mov bx,F1408HZ ;Warn user audibly
call Beep
mov bx,F176HZ
call Beep
Fb3: inc block ;next block,
dec blkcnt ;another...
jnz BlockLup ;keep looking.
ret
blkstr db CR,'Block $'
badstr db ' bad,$'
alrstr db ' already marked.',CR,LF,'$'
mrkstr db ' mapped out.',LF,'$'
cntstr db " already used! I don't know which file.",LF,'$'
abort db ' ... Aborting program',CR,LF,LF,'$'
FindBad endp
page
;
;Mark the current block as bad in the FAT.
;Multiply the block number by 1.5 to find the
;block number, (actually *3, /2) and if not
;used, mark it bad. If used, report which file
;it's in. If it's already mapped as bad,
;return CX=0, else return CX=1.
;
MapOut proc near
mov bx,block ;block,
shl bx,